package com.next

import grails.transaction.Transactional
import org.springframework.security.access.annotation.Secured

import static org.springframework.http.HttpStatus.*

@Secured(['ROLE_ADMINISTRATOR', 'ROLE_COMPANY_ADMINISTRATOR', 'ROLE_COMPANY_USER'])
@Transactional(readOnly = true)
class WorkflowInstanceController
{

    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
    def workflowInstanceService
    def springSecurityService

    def index(Integer max)
    {
        params.max = Math.min(max ?: 10, 100)
        max = 10
        params.max = Math.min(max ?: 10, 100)
        respond WorkflowInstance.list(params), model: [workflowInstanceCount: WorkflowInstance.count()]
    }

    def show(WorkflowInstance workflowInstance)
    {
        def workflowInstanceStages = WorkflowInstanceStage.findAll("from WorkflowInstanceStage where instance.id = ${workflowInstance?.id} order by executionSequence asc")
        respond workflowInstance, model: [workflowInstanceStages: workflowInstanceStages]
    }

    def create()
    {
        def targetUri = request.getHeader("referer")
        respond new WorkflowInstance(params), model: [targetUri: targetUri]
    }

    @Transactional
    def save(WorkflowInstance workflowInstance)
    {
        if (workflowInstance == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (workflowInstance.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond workflowInstance.errors, view: 'create', model: [targetUri: params['targetUri']]
            return
        }

        workflowInstance.save flush: true

        workflowInstanceService.initWorkflowInstance workflowInstance

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.created.message', args: [message(code: 'workflowInstance.label', default: 'WorkflowInstance'), workflowInstance.id])
                // redirect workflowInstance
                redirect uri: params['targetUri']
            }
            '*' { respond workflowInstance, [status: CREATED] }
        }
    }

    def edit(WorkflowInstance workflowInstance)
    {
        respond workflowInstance
    }

    @Transactional
    def update(WorkflowInstance workflowInstance)
    {
        if (workflowInstance == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (workflowInstance.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond workflowInstance.errors, view: 'edit'
            return
        }

        workflowInstance.save flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.updated.message', args: [message(code: 'workflowInstance.label', default: 'WorkflowInstance'), workflowInstance.id])
                redirect workflowInstance
            }
            '*' { respond workflowInstance, [status: OK] }
        }
    }

    @Transactional
    def delete(WorkflowInstance workflowInstance)
    {

        if (workflowInstance == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        workflowInstance.delete flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.deleted.message', args: [message(code: 'workflowInstance.label', default: 'WorkflowInstance'), workflowInstance.id])
                // redirect action: "index", method: "GET"
                redirect uri: request.getHeader("referer")
            }
            '*' { render status: NO_CONTENT }
        }
    }

    protected void notFound()
    {
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.not.found.message', args: [message(code: 'workflowInstance.label', default: 'WorkflowInstance'), params.id])
                redirect action: "index", method: "GET"
            }
            '*' { render status: NOT_FOUND }
        }
    }

    @Transactional
    def approve(WorkflowInstance workflowInstance)
    {
        def username = springSecurityService.getPrincipal().username
        def user = User.findByUsername(username)

        def stage = workflowInstance?.stage
        def map = [:]

        def authority = WorkflowAuthority.findByName("Approval")
        def workflowInstanceUser = WorkflowInstanceUser.findByStageAndUserAndAuthority(stage, user, authority)
        if (workflowInstanceUser)
        {
            map = workflowInstanceService.approve(workflowInstance)
            if (map['flag'])
            {
                stage = workflowInstance?.stage
                def operator = ""
                def workflowInstanceUsers = WorkflowInstanceUser.findAllByStage(stage)
                workflowInstanceUsers?.each {
                    operator += it?.user?.toString() + ","
                }
                if (workflowInstanceUsers?.size() > 0)
                {
                    operator = operator[0..operator.length() - 2]
                }
                flash.message = "已提交至${workflowInstance?.stage?.name}(${operator})"
                redirect uri: request.getHeader("referer")
                return
            }
            else
            {
                def message = map['message']
                if (message)
                {
                    flash.message = map['message']
                }
                else
                {
                    flash.message = "校验失败"
                }
                redirect uri: request.getHeader("referer")
                return
            }
        }
        else
        {
            flash.message = "没有操作权限"

            redirect uri: request.getHeader("referer")
            return
        }
    }

    @Transactional
    def reject(WorkflowInstance workflowInstance)
    {
        def username = springSecurityService.getPrincipal().username
        def user = User.findByUsername(username)
        def stage = workflowInstance?.stage
        def authority = WorkflowAuthority.findByName("Approval")
        def workflowInstanceUser = WorkflowInstanceUser.findByStageAndUserAndAuthority(stage, user, authority)
        def flag

        if (workflowInstanceUser)
        {
            flag = workflowInstanceService.reject(workflowInstance)
            if (flag)
            {
                flash.message = "回退操作成功！"
            }
            else
            {
                flash.message = "操作失败"
            }
        }
        else
        {
            flash.message = "没有操作权限"
        }
        redirect uri: request.getHeader("referer")
        return
    }

    @Transactional
    def cancel(WorkflowInstance workflowInstance)
    {
        def username = springSecurityService.getPrincipal().username
        def user = User.findByUsername(username)
        def stage = workflowInstance?.stage
        def authority = WorkflowAuthority.findByName("Approval")
        def workflowInstanceUser = WorkflowInstanceUser.findByStageAndUserAndAuthority(stage, user, authority)
        def flag
        if (workflowInstanceUser)
        {
            flag = workflowInstanceService.cancel(workflowInstance)
            if (flag)
            {
                flash.message = "工作流状态修改成功！"
            }
            else
            {
                flash.message = "操作失败"
            }
        }
        else
        {
            flash.message = "没有操作权限"
        }
        redirect uri: request.getHeader("referer")
        return
    }

    @Transactional
    def complete(WorkflowInstance workflowInstance)
    {
        def username = springSecurityService.getPrincipal().username
        def user = User.findByUsername(username)
        def stage = workflowInstance?.stage
        def authority = WorkflowAuthority.findByName("Approval")
        def workflowInstanceUser = WorkflowInstanceUser.findByStageAndUserAndAuthority(stage, user, authority)
        def flag
        if (workflowInstanceUser)
        {
            flag = workflowInstanceService.complete(workflowInstance)
            if (flag)
            {
                flash.message = "工作流状态修改成功！"
            }
            else
            {
                flash.message = "操作失败"
            }
        }
        else
        {
            flash.message = "没有操作权限"
        }
        redirect uri: request.getHeader("referer")
        return
    }

    def createWorkflowInstanceOnTask()
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        respond new WorkflowInstance(params), model: [user: user]
    }

    def createWorkflowInstanceOnIssue()
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        respond new WorkflowInstance(params), model: [user: user]
    }

    def createWorkflowInstanceOnAppointment()
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        respond new WorkflowInstance(params), model: [user: user]
    }

    @Transactional
    def createWorkflowInstanceOnAsset(WorkflowInstance workflowInstance)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        respond new WorkflowInstance(params), model: [user: user]
    }

    def createWorkflowInstanceOnOperation()
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        respond new WorkflowInstance(params), model: [user: user]
    }

    @Transactional
    def saveWorkflowInstanceOnTask(WorkflowInstance workflowInstance)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        if (workflowInstance == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (workflowInstance.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond workflowInstance.errors, model: [user: user], view: 'createWorkflowInstanceOnTask'
            return
        }

        if (workflowInstance?.activity?.validate())
        {

            workflowInstance.save flush: true

            workflowInstanceService.initWorkflowInstance workflowInstance

            request.withFormat {
                form multipartForm {
                    flash.message = message(code: 'default.created.message', args: [message(code: 'workflowInstance.label', default: 'WorkflowInstance'), workflowInstance.id])
                    // redirect workflowInstance
                    redirect(controller: "activity", action: "show", params: [id: workflowInstance?.activity?.id])
                }
                '*' { respond workflowInstance, [status: CREATED] }
            }
        }
        else
        {
            transactionStatus.setRollbackOnly()
            flash.message = workflowInstance?.activity.errors
            respond workflowInstance, model: [user: user], view: 'createWorkflowInstanceOnTask'
            return
        }
    }

    @Transactional
    def saveWorkflowInstanceOnIssue(WorkflowInstance workflowInstance)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        if (workflowInstance == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (workflowInstance.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond workflowInstance.errors, model: [user: user], view: 'createWorkflowInstanceOnIssue'
            return
        }

        if (workflowInstance?.issue?.validate())
        {

            workflowInstance.save flush: true

            workflowInstanceService.initWorkflowInstance workflowInstance

            request.withFormat {
                form multipartForm {
                    flash.message = message(code: 'default.created.message', args: [message(code: 'workflowInstance.label', default: 'WorkflowInstance'), workflowInstance.id])
                    // redirect workflowInstance
                    redirect(controller: "issue", action: "show", params: [id: workflowInstance?.issue?.id])
                }
                '*' { respond workflowInstance, [status: CREATED] }
            }
        }
        else
        {
            transactionStatus.setRollbackOnly()
            flash.message = workflowInstance?.issue.errors
            respond workflowInstance, model: [user: user], view: 'createWorkflowInstanceOnIssue'
            return
        }
    }

    @Transactional
    def saveWorkflowInstanceOnAppointment(WorkflowInstance workflowInstance)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        if (workflowInstance == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (workflowInstance.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond workflowInstance.errors, model: [user: user], view: 'createWorkflowInstanceOnAppointment'
            return
        }

        if (workflowInstance?.activity?.validate())
        {

            workflowInstance.save flush: true

            workflowInstanceService.initWorkflowInstance workflowInstance

            request.withFormat {
                form multipartForm {
                    flash.message = message(code: 'default.created.message', args: [message(code: 'workflowInstance.label', default: 'WorkflowInstance'), workflowInstance.id])
                    // redirect workflowInstance
                    redirect(controller: "activity", action: "show", params: [id: workflowInstance?.activity?.id])
                }
                '*' { respond workflowInstance, [status: CREATED] }
            }
        }
        else
        {
            transactionStatus.setRollbackOnly()
            flash.message = workflowInstance?.activity.errors
            respond workflowInstance, model: [user: user], view: 'createWorkflowInstanceOnAppointment'
            return
        }
    }

    @Transactional
    def saveWorkflowInstanceOnAsset(WorkflowInstance workflowInstance)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        if (workflowInstance == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (workflowInstance.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond workflowInstance.errors, model: [user: user], view: 'createWorkflowInstanceOnAsset'
            return
        }

        if (workflowInstance?.asset?.validate())
        {

            workflowInstance.save flush: true

            workflowInstanceService.initWorkflowInstance workflowInstance

            request.withFormat {
                form multipartForm {
                    flash.message = message(code: 'default.created.message', args: [message(code: 'workflowInstance.label', default: 'WorkflowInstance'), workflowInstance.id])
                    // redirect workflowInstance
                    redirect(controller: "asset", action: "show", params: [id: workflowInstance?.asset?.id])
                }
                '*' { respond workflowInstance, [status: CREATED] }
            }
        }
        else
        {
            transactionStatus.setRollbackOnly()
            flash.message = workflowInstance?.asset.errors
            respond workflowInstance, model: [user: user], view: 'createWorkflowInstanceOnAsset'
            return
        }
    }

    @Transactional
    def saveWorkflowInstanceOnOperation(WorkflowInstance workflowInstance)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        if (workflowInstance == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (workflowInstance.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond workflowInstance.errors, model: [user: user], view: 'createWorkflowInstanceOnOperation'
            return
        }

        if (workflowInstance?.activity?.validate())
        {
            workflowInstance.save flush: true

            workflowInstanceService.initWorkflowInstance workflowInstance

            request.withFormat {
                form multipartForm {
                    flash.message = message(code: 'default.created.message', args: [message(code: 'workflowInstance.label', default: 'WorkflowInstance'), workflowInstance.id])
                    // redirect workflowInstance
                    redirect(controller: "activity", action: "show", params: [id: workflowInstance?.activity?.id])
                }
                '*' { respond workflowInstance, [status: CREATED] }
            }

        }
        else
        {
            transactionStatus.setRollbackOnly()
            flash.message = workflowInstance?.activity.errors
            respond workflowInstance, model: [user: user], view: 'createWorkflowInstanceOnOperation'
            return
        }
    }

    @Transactional
    def creationWizard(WorkflowInstance workflowInstance)
    {
    }
}
